console.log("**************************************************************************");

/* 
    1. 成员初始化后（比如 age:number），才可以通过 this.age 来访问实例成员
    2. 需要为构造函数指定类型注解，否则会被隐式推断为any，构造函数不需要返回值类型
*/
class Person {
    // 实例属性初始化
    age: number
    gender: string

    // 构造函数
    constructor(age: number, gender: string) {
        this.age = age;
        this.gender = gender;
    }
}

// p 的类型是 Person
const p = new Person(6, "female");
console.log(p.age, p.gender);
/* **********************************class类实例方法***************************************** */
class Point {
    x = 1;
    y = 2;

    scale(n: number) {
        this.x *= n;
        this.y *= n;
    }
}

const point = new Point();
point.scale(10);
console.log(point.x, point.y);
/* **********************************class继承类***************************************** */
class Animal {
    move() {
        console.log("我会动");
    }
}

class Dog extends Animal {
    bark() {
        console.log("汪汪汪");
    }
}

const dog = new Dog();
dog.move();
dog.bark();
/* **********************************class实现接口***************************************** */
interface Sing{
    sing():void
}

class Lily implements Sing{
    sing(): void {
        console.log("我会唱歌啦啦啦");
    }
}
const lily = new Lily();
lily.sing();
/* **********************************class 成员可见性***************************************** */
/* 
    public, protected,private，readonly
        1. public 默认是public，可以省略
        2. protected 父类的其它方法中可见，子类方法中可见，但父类、子类的实例对象都不可见
        3. private  只在父类的其它方法中可见，子类中不可见，父类、子类的实例对象也不可见
        4. readonly 修饰关键字只读，只能修饰属性，不能修饰方法，可以设置默认值，只能在构造方法中修改
            接口或者{}表示的对象类型，也可以使用 readonly
*/
console.log("**************************************************************************");

// public 默认是public，可以省略
class Animal_public{
   public move1(){ // 默认是public
        console.log("class 类成员可见性__public");
    }
}

const animalA = new Animal_public();
animalA.move1();

// protected 父类的其它方法中可见，子类方法中可见，但父类、子类的实例对象都不可见
class Animal_protect{
    protected move2(){
        console.log("class类成员可见性__protected");
    }
    readMove2(){
        console.log("Animal_protect readMove2()");
        // protected 父类的其它方法中可见
        this.move2();
    }
}
const animalB = new Animal_protect();
// animalB.move2();  //move2() 对实例对象不可见 
class Animal_protect_child extends Animal_protect{
    // protected 子类方法中可见
    read(){
        console.log("Animal_protect_child： read()");
        this.move2();
    }
}
const animalB2 = new Animal_protect_child();
animalB2.read();

// 只读属性
class AnimalD{
    readonly age:number = 18 //age 后面的类型注解 :number  如果不写，age则会变成字面量类型 18
    constructor(age:number){
        this.age = age;
    }
}